package com.feather.common.text;

import java.io.UnsupportedEncodingException;
import java.text.SimpleDateFormat;

/**
 * @author flogyin
 */
public class StringUtil {
	/**
	 * 替换字符串函数
	 * 
	 * @parm strSource 源字符串
	 * @parm strFrom 要替换的子串
	 * @parm strTo 替换为的字符串
	 */
	public static String replace(String strSource, String strFrom, String strTo) {
		if (strSource == null || strFrom == null || strFrom.length() == 0) {
			return null;
		}
		if (strTo == null) {
			strTo = "";
		}
		StringBuilder destBuilder = new StringBuilder(strSource.length() * 2);
		int strFromLen = strFrom.length();
		int prevPos = 0, currPos = 0;
		while ((currPos = strSource.indexOf(strFrom, prevPos)) != -1) {// 循环替换字符串
			destBuilder.append(strSource.substring(prevPos, currPos));// 获取匹配字符串的左边子串
			destBuilder.append(strTo);// 加上替换后的子串
			prevPos = currPos + strFromLen;
		}
		if (prevPos != 0) {
			destBuilder.append(strSource.substring(prevPos, strSource.length()));// 加上没有匹配的子串
			return destBuilder.toString();
		} else {
			return strSource;
		}
	}

	public static int countChar(String source, char target) {
		int count = 0;
		if (source != null) {
			int at = source.indexOf(target);
			if (at != -1) {
				int prevAt = at + 1;
				while (at != -1) {
					count++;
					at = source.indexOf(target, prevAt);
					prevAt = at + 1;
				}
			}
		}
		return count;
	}

	public static String to62Char(long i) {
		if (i == 0) {
			return "0";
		}

		String chars = "";
		while (i > 0) {
			chars = convert62((int) (i % 62)) + chars;
			i = i / 62;
		}
		return chars;
	}

	public static String to52Char(long i) {
		if (i == 0) {
			return "0";
		}

		String chars = "";
		while (i > 0) {
			chars = convert52((int) (i % 52)) + chars;
			i = i / 52;
		}
		return chars;
	}

	public static String to36Char(long i) {
		if (i == 0) {
			return "0";
		}

		String chars = "";
		while (i > 0) {
			chars = convert36((int) (i % 36)) + chars;
			i = i / 36;
		}
		return chars;
	}

	public static String to26Char(long i) {
		if (i == 0) {
			return "0";
		}

		String chars = "";
		while (i > 0) {
			chars = convert26((int) (i % 26)) + chars;
			i = i / 26;
		}
		return chars;
	}

	public static long to62Number(String str) {
		int length;
		if (str == null || (length = str.length()) == 0) {
			return 0L;
		}

		long value = 0L;
		for (int i = 0; i < length; i++) {
			double val = Math.pow(62, (length - i - 1));
			value += convert62(str.charAt(i)) * val;
		}
		return value;
	}

	public static long to52Number(String str) {
		int length;
		if (str == null || (length = str.length()) == 0) {
			return 0L;
		}

		long value = 0L;
		for (int i = 0; i < length; i++) {
			double val = Math.pow(52, (length - i - 1));
			value += convert52(str.charAt(i)) * val;
		}
		return value;
	}

	public static long to36Number(String str) {
		int length;
		if (str == null || (length = str.length()) == 0) {
			return 0L;
		}

		long value = 0L;
		for (int i = 0; i < length; i++) {
			double val = Math.pow(36, (length - i - 1));
			value += convert36(str.charAt(i)) * val;
		}
		return value;
	}

	public static long to26Number(String str) {
		int length;
		if (str == null || (length = str.length()) == 0) {
			return 0L;
		}

		long value = 0L;
		for (int i = 0; i < length; i++) {
			double val = Math.pow(26, (length - i - 1));
			value += convert26(str.charAt(i)) * val;
		}
		return value;
	}

	public static char convert62(int val) {
		switch (val) {
			case 0:
				return '0';
			case 1:
				return '1';
			case 2:
				return '2';
			case 3:
				return '3';
			case 4:
				return '4';
			case 5:
				return '5';
			case 6:
				return '6';
			case 7:
				return '7';
			case 8:
				return '8';
			case 9:
				return '9';

			case 10:
				return 'a';
			case 11:
				return 'b';
			case 12:
				return 'c';
			case 13:
				return 'd';
			case 14:
				return 'e';
			case 15:
				return 'f';
			case 16:
				return 'g';
			case 17:
				return 'h';
			case 18:
				return 'i';
			case 19:
				return 'j';
			case 20:
				return 'k';
			case 21:
				return 'l';
			case 22:
				return 'm';
			case 23:
				return 'n';
			case 24:
				return 'o';
			case 25:
				return 'p';
			case 26:
				return 'q';
			case 27:
				return 'r';
			case 28:
				return 's';
			case 29:
				return 't';
			case 30:
				return 'u';
			case 31:
				return 'v';
			case 32:
				return 'w';
			case 33:
				return 'x';
			case 34:
				return 'y';
			case 35:
				return 'z';

			case 36:
				return 'A';
			case 37:
				return 'B';
			case 38:
				return 'C';
			case 39:
				return 'D';
			case 40:
				return 'E';
			case 41:
				return 'F';
			case 42:
				return 'G';
			case 43:
				return 'H';
			case 44:
				return 'I';
			case 45:
				return 'J';
			case 46:
				return 'K';
			case 47:
				return 'L';
			case 48:
				return 'M';
			case 49:
				return 'N';
			case 50:
				return 'O';
			case 51:
				return 'P';
			case 52:
				return 'Q';
			case 53:
				return 'R';
			case 54:
				return 'S';
			case 55:
				return 'T';
			case 56:
				return 'U';
			case 57:
				return 'V';
			case 58:
				return 'W';
			case 59:
				return 'X';
			case 60:
				return 'Y';
			case 61:
				return 'Z';
		}
		return '0';
	}

	public static char convert52(int val) {
		switch (val) {
			case 0:
				return 'a';
			case 1:
				return 'b';
			case 2:
				return 'c';
			case 3:
				return 'd';
			case 4:
				return 'e';
			case 5:
				return 'f';
			case 6:
				return 'g';
			case 7:
				return 'h';
			case 8:
				return 'i';
			case 9:
				return 'j';
			case 10:
				return 'k';
			case 11:
				return 'l';
			case 12:
				return 'm';
			case 13:
				return 'n';
			case 14:
				return 'o';
			case 15:
				return 'p';
			case 16:
				return 'q';
			case 17:
				return 'r';
			case 18:
				return 's';
			case 19:
				return 't';
			case 20:
				return 'u';
			case 21:
				return 'v';
			case 22:
				return 'w';
			case 23:
				return 'x';
			case 24:
				return 'y';
			case 25:
				return 'z';

			case 26:
				return 'A';
			case 27:
				return 'B';
			case 28:
				return 'C';
			case 29:
				return 'D';
			case 30:
				return 'E';
			case 31:
				return 'F';
			case 32:
				return 'G';
			case 33:
				return 'H';
			case 34:
				return 'I';
			case 35:
				return 'J';
			case 36:
				return 'K';
			case 37:
				return 'L';
			case 38:
				return 'M';
			case 39:
				return 'N';
			case 40:
				return 'O';
			case 41:
				return 'P';
			case 42:
				return 'Q';
			case 43:
				return 'R';
			case 44:
				return 'S';
			case 45:
				return 'T';
			case 46:
				return 'U';
			case 47:
				return 'V';
			case 48:
				return 'W';
			case 49:
				return 'X';
			case 50:
				return 'Y';
			case 51:
				return 'Z';
		}
		return '0';
	}

	public static char convert36(int val) {
		switch (val) {
			case 0:
				return '0';
			case 1:
				return '1';
			case 2:
				return '2';
			case 3:
				return '3';
			case 4:
				return '4';
			case 5:
				return '5';
			case 6:
				return '6';
			case 7:
				return '7';
			case 8:
				return '8';
			case 9:
				return '9';

			case 10:
				return 'A';
			case 11:
				return 'B';
			case 12:
				return 'C';
			case 13:
				return 'D';
			case 14:
				return 'E';
			case 15:
				return 'F';
			case 16:
				return 'G';
			case 17:
				return 'H';
			case 18:
				return 'I';
			case 19:
				return 'J';
			case 20:
				return 'K';
			case 21:
				return 'L';
			case 22:
				return 'M';
			case 23:
				return 'N';
			case 24:
				return 'O';
			case 25:
				return 'P';
			case 26:
				return 'Q';
			case 27:
				return 'R';
			case 28:
				return 'S';
			case 29:
				return 'T';
			case 30:
				return 'U';
			case 31:
				return 'V';
			case 32:
				return 'W';
			case 33:
				return 'X';
			case 34:
				return 'Y';
			case 35:
				return 'Z';
		}
		return '0';
	}

	public static char convert26(int val) {
		switch (val) {
			case 0:
				return 'A';
			case 1:
				return 'B';
			case 2:
				return 'C';
			case 3:
				return 'D';
			case 4:
				return 'E';
			case 5:
				return 'F';
			case 6:
				return 'G';
			case 7:
				return 'H';
			case 8:
				return 'I';
			case 9:
				return 'J';
			case 10:
				return 'K';
			case 11:
				return 'L';
			case 12:
				return 'M';
			case 13:
				return 'N';
			case 14:
				return 'O';
			case 15:
				return 'P';
			case 16:
				return 'Q';
			case 17:
				return 'R';
			case 18:
				return 'S';
			case 19:
				return 'T';
			case 20:
				return 'U';
			case 21:
				return 'V';
			case 22:
				return 'W';
			case 23:
				return 'X';
			case 24:
				return 'Y';
			case 25:
				return 'Z';
		}
		return '0';
	}

	public static int convert62(char c) {
		switch (c) {
			case '0':
				return 0;
			case '1':
				return 1;
			case '2':
				return 2;
			case '3':
				return 3;
			case '4':
				return 4;
			case '5':
				return 5;
			case '6':
				return 6;
			case '7':
				return 7;
			case '8':
				return 8;
			case '9':
				return 9;

			case 'a':
				return 10;
			case 'b':
				return 11;
			case 'c':
				return 12;
			case 'd':
				return 13;
			case 'e':
				return 14;
			case 'f':
				return 15;
			case 'g':
				return 16;
			case 'h':
				return 17;
			case 'i':
				return 18;
			case 'j':
				return 19;
			case 'k':
				return 20;
			case 'l':
				return 21;
			case 'm':
				return 22;
			case 'n':
				return 23;
			case 'o':
				return 24;
			case 'p':
				return 25;
			case 'q':
				return 26;
			case 'r':
				return 27;
			case 's':
				return 28;
			case 't':
				return 29;
			case 'u':
				return 30;
			case 'v':
				return 31;
			case 'w':
				return 32;
			case 'x':
				return 33;
			case 'y':
				return 34;
			case 'z':
				return 35;

			case 'A':
				return 36;
			case 'B':
				return 37;
			case 'C':
				return 38;
			case 'D':
				return 39;
			case 'E':
				return 40;
			case 'F':
				return 41;
			case 'G':
				return 42;
			case 'H':
				return 43;
			case 'I':
				return 44;
			case 'J':
				return 45;
			case 'K':
				return 46;
			case 'L':
				return 47;
			case 'M':
				return 48;
			case 'N':
				return 49;
			case 'O':
				return 50;
			case 'P':
				return 51;
			case 'Q':
				return 52;
			case 'R':
				return 53;
			case 'S':
				return 54;
			case 'T':
				return 55;
			case 'U':
				return 56;
			case 'V':
				return 57;
			case 'W':
				return 58;
			case 'X':
				return 59;
			case 'Y':
				return 60;
			case 'Z':
				return 61;
		}
		return 0;
	}

	public static int convert52(char c) {
		switch (c) {
			case 'a':
				return 0;
			case 'b':
				return 1;
			case 'c':
				return 2;
			case 'd':
				return 3;
			case 'e':
				return 4;
			case 'f':
				return 5;
			case 'g':
				return 6;
			case 'h':
				return 7;
			case 'i':
				return 8;
			case 'j':
				return 9;
			case 'k':
				return 10;
			case 'l':
				return 11;
			case 'm':
				return 12;
			case 'n':
				return 13;
			case 'o':
				return 14;
			case 'p':
				return 15;
			case 'q':
				return 16;
			case 'r':
				return 17;
			case 's':
				return 18;
			case 't':
				return 19;
			case 'u':
				return 20;
			case 'v':
				return 21;
			case 'w':
				return 22;
			case 'x':
				return 23;
			case 'y':
				return 24;
			case 'z':
				return 25;

			case 'A':
				return 26;
			case 'B':
				return 27;
			case 'C':
				return 28;
			case 'D':
				return 29;
			case 'E':
				return 30;
			case 'F':
				return 31;
			case 'G':
				return 32;
			case 'H':
				return 33;
			case 'I':
				return 34;
			case 'J':
				return 35;
			case 'K':
				return 36;
			case 'L':
				return 37;
			case 'M':
				return 38;
			case 'N':
				return 39;
			case 'O':
				return 40;
			case 'P':
				return 41;
			case 'Q':
				return 42;
			case 'R':
				return 43;
			case 'S':
				return 44;
			case 'T':
				return 45;
			case 'U':
				return 46;
			case 'V':
				return 47;
			case 'W':
				return 48;
			case 'X':
				return 49;
			case 'Y':
				return 50;
			case 'Z':
				return 51;
		}
		return 0;
	}

	public static int convert36(char c) {
		switch (c) {
			case '0':
				return 0;
			case '1':
				return 1;
			case '2':
				return 2;
			case '3':
				return 3;
			case '4':
				return 4;
			case '5':
				return 5;
			case '6':
				return 6;
			case '7':
				return 7;
			case '8':
				return 8;
			case '9':
				return 9;

			case 'A':
				return 10;
			case 'B':
				return 11;
			case 'C':
				return 12;
			case 'D':
				return 13;
			case 'E':
				return 14;
			case 'F':
				return 15;
			case 'G':
				return 16;
			case 'H':
				return 17;
			case 'I':
				return 18;
			case 'J':
				return 19;
			case 'K':
				return 20;
			case 'L':
				return 21;
			case 'M':
				return 22;
			case 'N':
				return 23;
			case 'O':
				return 24;
			case 'P':
				return 25;
			case 'Q':
				return 26;
			case 'R':
				return 27;
			case 'S':
				return 28;
			case 'T':
				return 29;
			case 'U':
				return 30;
			case 'V':
				return 31;
			case 'W':
				return 32;
			case 'X':
				return 33;
			case 'Y':
				return 34;
			case 'Z':
				return 35;
		}
		return 0;
	}

	public static int convert26(char c) {
		switch (c) {
			case 'A':
				return 0;
			case 'B':
				return 1;
			case 'C':
				return 2;
			case 'D':
				return 3;
			case 'E':
				return 4;
			case 'F':
				return 5;
			case 'G':
				return 6;
			case 'H':
				return 7;
			case 'I':
				return 8;
			case 'J':
				return 9;
			case 'K':
				return 10;
			case 'L':
				return 11;
			case 'M':
				return 12;
			case 'N':
				return 13;
			case 'O':
				return 14;
			case 'P':
				return 15;
			case 'Q':
				return 16;
			case 'R':
				return 17;
			case 'S':
				return 18;
			case 'T':
				return 19;
			case 'U':
				return 20;
			case 'V':
				return 21;
			case 'W':
				return 22;
			case 'X':
				return 23;
			case 'Y':
				return 24;
			case 'Z':
				return 25;
		}
		return 0;
	}

	public static String getDateTimeStr() {
		return getDateTimeStr(null);
	}

	public static String getDateTimeStr(String format) {
		SimpleDateFormat sdf = new SimpleDateFormat(format == null ? "yyyy-MM-dd HH:mm:ss" : format);
		return sdf.format(new java.util.Date());
	}

	String substr(String text, int max) {
		if (text == null || max == 0) {
			return "";
		}
		int length = text.length();
		if (length <= max) {
			return text;
		}
		if (max > 0) {
			return text.substring(0, max);
		}
		max = length + max;
		return max >= 0 ? text.substring(max) : text;
	}

	String subRight(String text, int max) {
		if (text == null || max == 0) {
			return "";
		}
		return text.length() > max && max > -1 ? text.substring(0, max) : text;
	}

	public static String leftBinString(String src, int max, String encoding) throws UnsupportedEncodingException {
		String subStr = src;

		int length = src != null ? src.length() : 0;
		if (length * 3 > max) {
			StringBuilder builder = new StringBuilder(64);
			for (int i = 0, count = 0; i < length; i++) {
				String c = src.substring(i, i + 1);
				count += encoding != null ? c.getBytes(encoding).length : c.getBytes().length;

				if (count == max) {
					builder.append(c);
					break;
				} else if (count > max) {
					break;
				} else if (count < max) {
					builder.append(c);
				}
			}
			subStr = builder.toString();
		}
		return subStr;
	}

	public static String concat(String[] array, String separator) {
		StringBuilder builder = new StringBuilder();
		if (array != null) {
			for (String item : array) {
				if (builder.length() > 0) {
					builder.append(separator);
				}
				builder.append(item);
			}
		}
		return builder.toString();
	}

	public static String[] insertPrefix(String[] array, String prefix) {
		String[] newArr = null;
		if (array != null) {
			newArr = new String[array.length];
			for (int i = 0; i < array.length; i++) {
				newArr[i] = prefix + array[i];
			}
		}
		return newArr;
	}

	public static boolean inArray(String[] array, String suffix) {
		if (array != null && suffix != null) {
			for (String item : array)
				if (suffix.equalsIgnoreCase(item))
					return true;
		}
		return false;
	}

	public static boolean endWithArray(String[] array, String name) {
		if (array != null && name != null) {
			name = name.trim().toLowerCase();
			for (String item : array)
				if (name.endsWith(item))
					return true;
		}
		return false;
	}

	public static String getPair(String[] array, String type) {
		for (int i = 0; i < array.length; i += 2) {
			if (array[i].equals(type))
				return array[i + 1];
		}
		return "";
	}

	public static boolean findInSet(String set, String target, String separator) {
		if (set != null && target != null) {
			set = separator + set + separator;
			target = separator + target + separator;
			return set.indexOf(target) != -1;
		}
		return false;
	}
}
